package cn.itcast.service;

import cn.itcast.constant.RedisConstant;
import cn.itcast.interfaces.SetmealService;
import cn.itcast.mapper.SetmealMapper;
import cn.itcast.pojo.PageResult;
import cn.itcast.pojo.Setmeal;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.reactivex.Observable;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: peterChen
 * @date: 2019/8/13 20:29
 * @description: TODO
 * @version: 1.0
 */
@Service(interfaceClass = SetmealService.class)
@Transactional
@Slf4j
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private JedisPool jedisPool;


    /**
     * 新增套餐
     * @param setmeal
     * @param checkgroupIds
     */
    @Override
    public void add(Setmeal setmeal, Integer[] checkgroupIds) {
        //添加套餐，返回新增套餐的id
        setmealMapper.add(setmeal);
        String img = setmeal.getImg();
        //将添加进数据库的图片名称缓存进reidis
        jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,img);
        //关联套餐和检查组
        setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds);
    }

    public void setSetmealAndCheckGroup(Integer setmealId,Integer[] checkgroupIds){
        List<Map> list = new ArrayList<>();
        Map<String,Object> map = new HashMap<>();
        if(!ObjectUtils.isEmpty(checkgroupIds) && checkgroupIds.length>0){
            /*for (Integer checkgroupId : checkgroupIds) {
                map.put("setmealId",setmealId);
                map.put("checkgroupId",checkgroupId);
                list.add(map);
            }*/
            //Rxjava遍历数组
            Observable.fromArray(checkgroupIds).subscribe((checkgroupId)->{
                map.put("setmealId",setmealId);
                map.put("checkgroupId",checkgroupId);
                list.add(map);
            });
            setmealMapper.setSetmealAndCheckGroup(list);
        }
    }

    /**
     * 查询套餐分页数据
     * @param currentPage
     * @param pageSize
     * @param queryString
     * @return
     */
    @Override
    public PageResult pageQuery(Integer currentPage, Integer pageSize, String queryString) {
        PageHelper.startPage(currentPage,pageSize);
        Page page = setmealMapper.selectByCondition(queryString);
        return new PageResult(page.getTotal(),page.getResult());
    }

    /**
     * 根据id获取套餐数据
     * @param id
     * @return
     */
    @Override
    public Setmeal findSetmealById(Integer id) {
        return setmealMapper.findSetmealById(id);
    }

    /**
     * 根据套餐id获取关联的检查组的id
     * @param id
     * @return
     */
    @Override
    public List<Integer> findCheckgroupIdsBySetmealId(Integer id) {
        return setmealMapper.findCheckgroupIdsBySetmealId(id);
    }

    /**
     * 编辑套餐
     * @param setmeal
     * @param checkgroupIds
     */
    @Override
    public void edit(Setmeal setmeal, Integer[] checkgroupIds) {
        //解除套餐和检查组的关联
        setmealMapper.deleteAssociation(setmeal.getId());
        //重新关联新的检查组
        setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds);
        //更新套餐的信息
        setmealMapper.edit(setmeal);
    }

    /**
     * 根据id删除套餐
     * @param id
     */
    @Override
    public void delete(Integer id) {
        //解除套餐与检查组的关联
        setmealMapper.deleteAssociation(id);
        //删除套餐
        setmealMapper.delete(id);
    }

    /**
     * 获取套餐列表，移动端展示（redis缓存获取）
     * @return
     */
    @Override
    public List<Setmeal> getSetmeal() {
        //1.从redis中获取所有套餐对应的json字符串
        String setmeals = jedisPool.getResource().get(RedisConstant.SETMEAL_DB_ALLRESOURCES);
        List<Setmeal> setmealList = null;
        if(!StringUtils.isEmpty(setmeals)){
            log.debug("get setmealList from redis");
            //json非空，redis缓存中套餐列表有数据，利用JSON的parseArray方法传入字符串及泛型字节码对象转化为list集合
            setmealList = JSON.parseArray(setmeals,Setmeal.class);
        }else{
            log.debug("get setmealList from db");
            //json为空，没有该数据，从数据库查询
            setmealList = setmealMapper.getSetmeal();
            //将查询到的数据缓存入redis中,设置缓存寿命，以便数据库更新数据后（定期）更新到redis缓存中
            jedisPool.getResource().setex(RedisConstant.SETMEAL_DB_ALLRESOURCES,30*60*60,JSON.toJSONString(setmealList));
        }
        return setmealList;
    }

    /**
     * 根据id获取套餐的全部信息（检查组、检查项）
     * @param id
     * @return
     */
    @Override
    public Setmeal findById(Integer id) {
        String setmealDetail = jedisPool.getResource().get(id + RedisConstant.SETMEAL_DETAIL_RESOURCES);
        Setmeal setmeal = null;
        if(!StringUtils.isEmpty(setmealDetail)){
            //redis中获取的套餐不为空，json字符串转化为setmeal对象
            setmeal = (Setmeal) JSON.parse(setmealDetail);
        }else{
            //为空，表示缓存中无该数据，从数据库中查询,并将查询到的信息缓存入redis中
            setmeal = setmealMapper.findById(id);
            //缓存入redis中，设置寿命，以便定时更新数据库中的最新详情到redis中
            jedisPool.getResource().setex(id + RedisConstant.SETMEAL_DETAIL_RESOURCES,30*60*60,JSON.toJSONString(setmeal));
        }
        return setmeal;
    }

    /**
     * 获取套餐名及对应的套餐预约数量
     * @return
     */
    @Override
    public List<Map<String, Object>> findSetmealCount() {
        return  setmealMapper.findSetmealCount();
    }

    /**
     * 获取性别对应的会员数量
     * @return
     */
    @Override
    public List<Map<String, Object>> getSexReport() {
        return setmealMapper.findMemberCountBySex();
    }
}
